﻿#ifndef THREAD_H
#define THREAD_H

#include <QThread>
#include <QDebug>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
#include <Python.h>
#include <numpy/arrayobject.h>
#include <QMutex>
#include "SapClassBasic.h"


extern int index;
extern char dirpath[10];
extern PyObject* PFun1;
extern PyObject* PFun2;

void onImageDataCallback(SapXferCallbackInfo *pInfo);
void onImageForLearnCallback(SapXferCallbackInfo *pInfo);


//PyThreadStateLock类为python全局锁的加锁和释放，主线程初始化python需要的资源，返回调用函数的指针到全局变量中，之后主线程放弃全局锁。
//子线程若需要调用python文件中的函数，需要拿到全局锁。
//使用方法：若要获得全局锁，实例化PyThreadStateLock调用构造函数自动拿取全局锁。子线程退出时，作用域结束，自动调用类的析构函数，完成解锁
//即只需在调用python的线程入口函数中先实例化PyThreadStateLock
class PyThreadStateLock
{
public:
    PyThreadStateLock(void)
    {
        state = PyGILState_Ensure( );
    }

    ~PyThreadStateLock(void)
    {
         PyGILState_Release( state );
    }
private:
    PyGILState_STATE state;
};



class QThreadRead: public QThread
{   Q_OBJECT

private:

protected:
    void run();

public:
   explicit QThreadRead(QObject *parent = NULL);
   bool m_stop;
   void exitThread();
   QMutex* m_mutex;

};


class QThreadDeal: public QThread
{   Q_OBJECT

private:

protected:
    void run();

public:
    explicit QThreadDeal(QObject *parent = NULL);
    bool m_stop;
    //PyObject* initpythonmodule();
    PyObject* call_python_file(npy_intp* diminfo,unsigned char* buff);
    void deal_ret_from_python(PyObject* ret);
    void exitThread();
    QMutex* m_mutex;
    PyObject *pModule;
    PyObject* pDict;
signals:
    void sendimage(cv::Mat image);
    void sendRes(int);
};

class ReadForLearn: public QThread
{   Q_OBJECT

private:

protected:
    void run();

public:
   explicit ReadForLearn(QObject *parent = NULL);
   bool m_stop;
   void exitThread();
   QMutex* m_mutex;

signals:
   //void sendimage2(cv::Mat);

};

class QThreadLearn: public QThread
{   Q_OBJECT
protected:
    void run();
public:
   explicit QThreadLearn(QObject *parent = NULL);
   //PyObject* initpythonmodule();
   void train_model();
signals:
   void learnCompelete();
};

class QThreadDisplay: public QThread
{   Q_OBJECT
protected:
    void run();
public:
   explicit QThreadDisplay(QObject *parent = NULL);
signals:
   void sendimage2(cv::Mat);
};


#endif // THREAD_H
